home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / varia / grammar2.lha / c++grammar2.0 / grammar5 / cpp5.y next >
GNU Bison Grammar  |  1991-07-05  |  87KB  |  2,311 lines

  1. %{
  2.  
  3.     /* Copyright (C) 1989-1991 James A. Roskind, All rights reserved. 
  4.     This grammar was developed  and  written  by  James  A.  Roskind. 
  5.     Copying  of  this  grammar  description, as a whole, is permitted 
  6.     providing this notice is intact and applicable  in  all  complete 
  7.     copies.   Translations as a whole to other parser generator input 
  8.     languages  (or  grammar  description  languages)   is   permitted 
  9.     provided  that  this  notice is intact and applicable in all such 
  10.     copies,  along  with  a  disclaimer  that  the  contents  are   a 
  11.     translation.   The reproduction of derived text, such as modified 
  12.     versions of this grammar, or the output of parser generators,  is 
  13.     permitted,  provided  the  resulting  work includes the copyright 
  14.     notice "Portions Copyright (c)  1989,  1990  James  A.  Roskind". 
  15.     Derived products, such as compilers, translators, browsers, etc., 
  16.     that  use  this  grammar,  must also provide the notice "Portions 
  17.     Copyright  (c)  1989,  1990  James  A.  Roskind"  in   a   manner 
  18.     appropriate  to  the  utility,  and in keeping with copyright law 
  19.     (e.g.: EITHER displayed when first invoked/executed; OR displayed 
  20.     continuously on display terminal; OR via placement in the  object 
  21.     code  in  form  readable in a printout, with or near the title of 
  22.     the work, or at the end of the file).  No royalties, licenses  or 
  23.     commissions  of  any  kind are required to copy this grammar, its 
  24.     translations, or derivative products, when the copies are made in 
  25.     compliance with this notice. Persons or corporations that do make 
  26.     copies in compliance with this notice may charge  whatever  price 
  27.     is  agreeable  to  a  buyer, for such copies or derivative works. 
  28.     THIS GRAMMAR IS PROVIDED ``AS IS'' AND  WITHOUT  ANY  EXPRESS  OR 
  29.     IMPLIED  WARRANTIES,  INCLUDING,  WITHOUT LIMITATION, THE IMPLIED 
  30.     WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR 
  31.     PURPOSE.
  32.  
  33.     James A. Roskind
  34.     Independent Consultant
  35.     516 Latania Palm Drive
  36.     Indialantic FL, 32903
  37.     (407)729-4348
  38.     jar@hq.ileaf.com
  39.  
  40.  
  41.     ---end of copyright notice---
  42.  
  43. MOTIVATION-
  44.  
  45. My  goal  is  to  see  software  developers  adopt  this grammar as a 
  46. standard until such time as a better  standard  is  accessible.   The 
  47. only  way  to  get it to become a standard, is to be sure that people 
  48. know that derivations are based on a specific work.   The  intent  of 
  49. releasing  this  grammar is to provide a publicly accessible standard 
  50. grammar for C++.  The intent of the  copyright  notice  is  to  allow 
  51. arbitrary  commercial  and non-commercial use of the grammar, as long 
  52. as reference is given to the original standard.  Without reference to 
  53. a specific standard, many alternative  grammars  would  develop.   By 
  54. referring  to  the  standard,  this grammar is given publicity, which 
  55. should lead to further use in compatible products and  systems.   The 
  56. benefits  of  such  a  standard  to  commercial  products  (browsers, 
  57. beautifiers, translators, compilers, ...) should be  obvious  to  the 
  58. developers,  in  that  other compatible products will emerge, and the 
  59. value of all conforming products  will  rise.   Most  developers  are 
  60. aware  of  the  value  of  acquiring  a fairly complete grammar for a 
  61. language, and the copyright notice  (and  the  resulting  affiliation 
  62. with my work) should not be too high a price to pay.  By copyrighting 
  63. this  grammar,  I have some minor control over what this standard is, 
  64. and I can (hopefully) keep it from degrading without my approval.   I 
  65. will  consistently  attempt  to  provide  upgraded  grammars that are 
  66. compliant  with  the  current  art,  and  the  ANSI   C++   Committee 
  67. recommendation  in  particular.   A developer is never prevented from 
  68. modifying the grammar to improve it in  whatever  way  is  seen  fit.  
  69. There  is  also  no  restriction on the sale of copies, or derivative 
  70. works, providing the requests in the copyright notice are satisfied.
  71.  
  72. If you are not "copying" my work, but  are  rather  only  abstracting 
  73. some  of  the  standard,  an acknowledgment with references to such a 
  74. standard would be appreciated.  Specifically,  agreements  with  this 
  75. standard  as  to  the  resolution  of otherwise ambiguous constructs, 
  76. should be noted.
  77.  
  78. Simply put: "make whatever use you would like  of  the  grammar,  but 
  79. include  the  ``portions  Copyright  ...''  as  a  reference  to this 
  80. standard."
  81.  
  82.  
  83. */
  84.  
  85.  
  86. /* Last modified 7/4/91, Version 2.0  */
  87.  
  88. /* File CPP5.Y is translated by YACC to Y.TAB.C */
  89.  
  90. /*  ACKNOWLEDGMENT: Without Bjarne Stroustrup and his many co-workers 
  91. at Bell Labs, there would be no C++ Language for which to  provide  a 
  92. syntax  description. Bjarne has also been especially helpful and open 
  93. in discussions, and by permitting me to review  his  texts  prior  to 
  94. their publication, allowed me a wonderful vantage point of clarity.
  95.  
  96. Without  the effort expended by the ANSI C standardizing committee, I 
  97. would have been lost.  Although the ANSI C standard does not  include 
  98. a  fully disambiguated syntax description, the committee has at least 
  99. provided most of the disambiguating rules in  narratives.   This  C++ 
  100. grammar  is intended to be a superset of an ANSI C compatible grammar 
  101. that is provided in an related file.
  102.  
  103. Several reviewers have also  recently  critiqued  this  grammar,  the 
  104. related  C  grammar,  and  or  assisted  in  discussions  during it's 
  105. preparation.  These reviewers are certainly not responsible  for  the 
  106. errors  I  have committed here, but they are responsible for allowing 
  107. me  to  provide  fewer  errors.   These  colleagues  include:   Bruce 
  108. Blodgett,  Mark Langley, Joe Fialli, Greg Perkins, Ron Guilmette, and 
  109. Eric Krohn. */
  110.  
  111. /* Required fixes from last release :
  112.  
  113. done: 0) Allow direct call to destructors
  114.  
  115. done: 1) Allow placement of declarations in labeled statements.   The 
  116. easiest  fix involves using a larger variance from the C grammar, and 
  117. simply making "statement" include declarations.  Note that it  should 
  118. also  be  legal  for  declarations  to  be  in  the  branches  of  if 
  119. statements, as long as there is no other code in the block (I think).  
  120. Consider:
  121.  
  122.         ...
  123.         {
  124.            if (0 == a)
  125.                 int b=5;
  126.            else
  127.                 int c=4;
  128.          }
  129.  
  130. 1) template support: Not  done:  pending  syntax  specification  from 
  131. ANSI.  (This looks like a major effort, as ANSI has decided to extend 
  132. the  "TYPEDEFname"-feedback-to-the-lexer-hack  to  support   template 
  133. names as a new kind of terminal token.)
  134.  
  135. 2)  exception  handling:  Not done: pending syntax specification from 
  136. ANSI (but it doesn't look hard)
  137.  
  138. done: 3) Support nested types, including identifier::name,  where  we 
  139. realize  that  identifier was a hidden type.  Force the lexer to keep 
  140. pace in this situation.   This  will  require  an  extension  of  the 
  141. yacc-lex feedback loop.
  142.  
  143. done: 4) Support nested types even when derivations are used in class 
  144. definitions.
  145.  
  146. 5)  Provide  advanced  tutorial  on  YACC  conflicts:  almost done in 
  147. documentation about machine generated documentation.
  148.  
  149. done: 6) Allow declaration specifiers to be left out of  declarations 
  150. at file and structure scope so that operator conversion functions can 
  151. be  declared and/or defined.  Note that checking to see that it was a 
  152. function type that does not require declaration_specifiers is  now  a 
  153. constraint  check,  and  not  a  syntax  issue.  Within function body 
  154. scopes, declaration specifiers are required, and this is critical  to 
  155. distinguishing expressions.
  156.  
  157.  
  158. */
  159.  
  160. %}
  161.  
  162. /*
  163.  
  164. Interesting ambiguity:
  165. Usually
  166.         typename ( typename2 ) ...
  167. or
  168.         typename ( typename2 [4] ) ...
  169. etc.
  170. is a redeclaration of typename2.
  171.  
  172. Inside  a structure elaboration, it is sometimes the declaration of a 
  173. constructor!  Note, this only  counts  if  typename  IS  the  current 
  174. containing  class name. (Note this can't conflict with ANSI C because 
  175. ANSI C would call it a redefinition, but  claim  it  is  semantically 
  176. illegal because you can't have a member declared the same type as the 
  177. containing struct!) Since the ambiguity is only reached when a ';' is 
  178. found,   there  is  no  problem  with  the  fact  that  the  semantic 
  179. interpretation  is  providing  the  true  resolution.   As  currently 
  180. implemented, the constructor semantic actions must be able to process 
  181. an  ordinary  declaration.  I may reverse this in the future, to ease 
  182. semantic implementation.
  183.  
  184. */
  185.  
  186.  
  187.  
  188. /*
  189.  
  190. INTRO TO ANSI C GRAMMAR (provided in a separate file):
  191.  
  192. The refined grammar resolves several typedef ambiguities in the draft 
  193. proposed ANSI C standard syntax down to 1 shift/reduce  conflict,  as 
  194. reported by a YACC process.  Note that the one shift reduce conflicts 
  195. is  the  traditional  if-if-else conflict that is not resolved by the 
  196. grammar.  This ambiguity can be removed using the method described in 
  197. the Dragon Book (2nd edition), but this does  not  appear  worth  the 
  198. effort.
  199.  
  200. There  was quite a bit of effort made to reduce the conflicts to this 
  201. level, and an additional effort was made to make  the  grammar  quite 
  202. similar  to  the  C++ grammar being developed in parallel.  Note that 
  203. this grammar resolves the following ANSI C ambiguities:
  204.  
  205. ANSI C section 3.5.6, "If the [typedef  name]  is  redeclared  at  an 
  206. inner  scope,  the  type specifiers shall not be omitted in the inner 
  207. declaration".  Supplying type specifiers prevents consideration of  T 
  208. as a typedef name in this grammar.  Failure to supply type specifiers 
  209. forced the use of the TYPEDEFname as a type specifier.  This is taken 
  210. to an (unnecessary) extreme by this implementation.  The ambiguity is 
  211. only  a  problem  with  the first declarator in a declaration, but we 
  212. restrict  ALL  declarators  whenever  the  users  fails  to   use   a 
  213. type_specifier.
  214.  
  215. ANSI C section 3.5.4.3, "In a parameter declaration, a single typedef 
  216. name  in  parentheses  is  taken  to  be  an abstract declarator that 
  217. specifies a function  with  a  single  parameter,  not  as  redundant 
  218. parentheses  around  the  identifier".  This is extended to cover the 
  219. following cases:
  220.  
  221. typedef float T;
  222. int noo(const (T[5]));
  223. int moo(const (T(int)));
  224. ...
  225.  
  226. Where again the '(' immediately to the left of 'T' is interpreted  as 
  227. being  the  start  of  a  parameter type list, and not as a redundant 
  228. paren around a redeclaration of T.  Hence an equivalent code fragment 
  229. is:
  230.  
  231. typedef float T;
  232. int noo(const int identifier1 (T identifier2 [5]));
  233. int moo(const int identifier1 (T identifier2 (int identifier3)));
  234. ...
  235.  
  236. */
  237.  
  238.  
  239. %{
  240. /*************** Includes and Defines *****************************/
  241. #define YYDEBUG_LEXER_TEXT (yylval) /* our lexer loads this up each time.
  242.                      We are telling the graphical debugger
  243.                      where to find the spelling of the 
  244.                      tokens.*/
  245. #define YYDEBUG 1        /* get the pretty debugging code to compile*/
  246. #define YYSTYPE  char *  /* interface with flex: should be in header file */
  247.  
  248. /*************** Standard ytab.c continues here *********************/
  249. %}
  250.  
  251. /*************************************************************************/
  252.  
  253.  
  254. /* This group is used by the C/C++ language parser */
  255. %token AUTO            DOUBLE          INT             STRUCT
  256. %token BREAK           ELSE            LONG            SWITCH
  257. %token CASE            ENUM            REGISTER        TYPEDEF
  258. %token CHAR            EXTERN          RETURN          UNION
  259. %token CONST           FLOAT           SHORT           UNSIGNED
  260. %token CONTINUE        FOR             SIGNED          VOID
  261. %token DEFAULT         GOTO            SIZEOF          VOLATILE
  262. %token DO              IF              STATIC          WHILE
  263.  
  264. /* The following are used in C++ only.  ANSI C would call these IDENTIFIERs */
  265. %token NEW             DELETE
  266. %token THIS
  267. %token OPERATOR
  268. %token CLASS
  269. %token PUBLIC          PROTECTED       PRIVATE
  270. %token VIRTUAL         FRIEND
  271. %token INLINE          OVERLOAD
  272.  
  273. /* ANSI C Grammar suggestions */
  274. %token IDENTIFIER              STRINGliteral
  275. %token FLOATINGconstant        INTEGERconstant        CHARACTERconstant
  276. %token OCTALconstant           HEXconstant
  277.  
  278. /* New Lexical element, whereas ANSI C suggested non-terminal */
  279. %token TYPEDEFname
  280.  
  281. /* Multi-Character operators */
  282. %token  ARROW            /*    ->                              */
  283. %token  ICR DECR         /*    ++      --                      */
  284. %token  LS RS            /*    <<      >>                      */
  285. %token  LE GE EQ NE      /*    <=      >=      ==      !=      */
  286. %token  ANDAND OROR      /*    &&      ||                      */
  287. %token  ELLIPSIS         /*    ...                             */
  288.                  /* Following are used in C++, not ANSI C        */
  289. %token  CLCL             /*    ::                              */
  290. %token  DOTstar ARROWstar/*    .*       ->*                    */
  291.  
  292. /* modifying assignment operators */
  293. %token MULTassign  DIVassign    MODassign   /*   *=      /=      %=      */
  294. %token PLUSassign  MINUSassign              /*   +=      -=              */
  295. %token LSassign    RSassign                 /*   <<=     >>=             */
  296. %token ANDassign   ERassign     ORassign    /*   &=      ^=      |=      */
  297.  
  298. /*************************************************************************/
  299.  
  300. %start translation_unit
  301.  
  302. /*************************************************************************/
  303.  
  304. %%
  305.  
  306. /*********************** CONSTANTS *********************************/
  307. constant:
  308.         INTEGERconstant
  309.         | FLOATINGconstant
  310.         /*  We  are not including ENUMERATIONconstant here because we 
  311.           are treating it like a variable with a type of "enumeration 
  312.           constant".  */
  313.         | OCTALconstant
  314.         | HEXconstant
  315.         | CHARACTERconstant
  316.         ;
  317.  
  318. string_literal_list:
  319.                 STRINGliteral
  320.                 | string_literal_list STRINGliteral
  321.                 ;
  322.  
  323.  
  324. /************************* EXPRESSIONS ********************************/
  325.  
  326.  
  327.     /* Note that I provide  a  "scope_opt_identifier"  that  *cannot* 
  328.     begin  with ::.  This guarantees we have a viable declarator, and 
  329.     helps to disambiguate :: based uses in the grammar.  For example:
  330.  
  331.             ...
  332.             {
  333.             int (* ::b()); // must be an expression
  334.             int (T::b); // officially a declaration, which fails on constraint grounds
  335.  
  336.     This *syntax* restriction reflects the current syntax in the ANSI 
  337.     C++ Working Papers.   This  means  that  it  is  *incorrect*  for 
  338.     parsers to misparse the example:
  339.  
  340.             int (* ::b()); // must be an expression
  341.  
  342.     as a declaration, and then report a constraint error.
  343.  
  344.     In contrast, declarations such as:
  345.  
  346.         class T;
  347.         class A;
  348.         class B;
  349.         main(){
  350.               T( F());  // constraint error: cannot declare local function
  351.               T (A::B::a); // constraint error: cannot declare member as a local value
  352.  
  353.     are  *parsed*  as  declarations,  and *then* given semantic error 
  354.     reports.  It is incorrect for a parser to "change its mind" based 
  355.     on constraints.  If your C++ compiler claims  that  the  above  2 
  356.     lines are expressions, then *I* claim that they are wrong. */
  357.  
  358. paren_identifier_declarator:
  359.         scope_opt_identifier
  360.         | scope_opt_complex_name
  361.         | '(' paren_identifier_declarator ')'
  362.         ;
  363.  
  364.  
  365.     /* Note that CLCL IDENTIFIER is NOT part of scope_opt_identifier, 
  366.     but  it  is  part of global_opt_scope_opt_identifier.  It is ONLY 
  367.     valid for referring to an identifier, and NOT valid for declaring 
  368.     (or importing an external declaration of)  an  identifier.   This 
  369.     disambiguates  the  following  code,  which  would  otherwise  be 
  370.     syntactically and semantically ambiguous:
  371.  
  372.             class base {
  373.                 static int i; // element i;
  374.                 float member_function(void);
  375.                 };
  376.             base i; // global i
  377.             float base::member_function(void) {
  378.                 i; // refers to static int element "i" of base
  379.                 ::i; // refers to global "i", with type "base"
  380.                     {
  381.                     base :: i; // import of global "i", like "base (::i);"?
  382.                                 // OR reference to global??
  383.                     }
  384.                 }
  385.         */
  386.  
  387. primary_expression:
  388.         global_opt_scope_opt_identifier
  389.         | global_opt_scope_opt_complex_name
  390.         | THIS   /* C++, not ANSI C */
  391.         | constant
  392.         | string_literal_list
  393.         | '(' comma_expression ')'
  394.         ;
  395.  
  396.  
  397.     /* I had to disallow struct, union, or enum  elaborations  during 
  398.     operator_function_name.   The  ANSI  C++  Working  paper is vague 
  399.     about whether this should be part of the syntax, or a constraint.  
  400.     The ambiguities that resulted were more than LALR  could  handle, 
  401.     so  the  easiest  fix was to be more specific.  This means that I 
  402.     had to in-line expand type_specifier_or_name far  enough  that  I 
  403.     would  be  able to exclude elaborations.  This need is what drove 
  404.     me to distinguish a whole series of tokens based on whether  they 
  405.     include elaborations:
  406.  
  407.          struct A { ... }
  408.  
  409.     or simply a reference to an aggregate or enumeration:
  410.  
  411.          enum A
  412.  
  413.     The  latter,  as  well  an  non-aggregate  types are what make up 
  414.     non_elaborating_type_specifier */
  415.  
  416.     /* Note that the following does not include  type_qualifier_list. 
  417.     Hence,   whenever   non_elaborating_type_specifier  is  used,  an 
  418.     adjacent rule is supplied containing type_qualifier_list.  It  is 
  419.     not  generally  possible  to  know  immediately  (i_e., reduce) a 
  420.     type_qualifier_list, as a TYPEDEFname that follows might  not  be 
  421.     part of a type specifier, but might instead be "TYPEDEFname ::*".  
  422.     */
  423.  
  424. non_elaborating_type_specifier:
  425.         sue_type_specifier
  426.         | basic_type_specifier
  427.         | typedef_type_specifier
  428.  
  429.         | basic_type_name
  430.         | TYPEDEFname
  431.         | global_or_scoped_typedefname
  432.         ;
  433.  
  434.  
  435.     /*  The  following  introduces  MANY  conflicts.   Requiring  and 
  436.     allowing '(' ')' around the `type' when the type is complex would 
  437.     help a lot. */
  438.  
  439. operator_function_name:
  440.         OPERATOR any_operator
  441.         | OPERATOR type_qualifier_list            operator_function_ptr_opt
  442.         | OPERATOR non_elaborating_type_specifier operator_function_ptr_opt
  443.         ;
  444.  
  445.  
  446.     /* The following causes several ambiguities on *  and  &.   These 
  447.     conflicts  would also be removed if parens around the `type' were 
  448.     required in the derivations for operator_function_name */
  449.  
  450.     /*  Interesting  aside:  The  use  of  right  recursion  in   the 
  451.     production  for  operator_function_ptr_opt gives both the correct 
  452.     parsing, AND removes a conflict!   Right  recursion  permits  the 
  453.     parser  to  defer  reductions  (a.k.a.:  delay  resolution),  and 
  454.     effectively make a second pass! */
  455.  
  456. operator_function_ptr_opt:
  457.         /* nothing */
  458.         | unary_modifier        operator_function_ptr_opt
  459.         | asterisk_or_ampersand operator_function_ptr_opt
  460.         ;
  461.  
  462.  
  463.     /* List of operators we can overload */
  464. any_operator:
  465.         '+'
  466.         | '-'
  467.         | '*'
  468.         | '/'
  469.         | '%'
  470.         | '^'
  471.         | '&'
  472.         | '|'
  473.         | '~'
  474.         | '!'
  475.         | '<'
  476.         | '>'
  477.         | LS
  478.         | RS
  479.         | ANDAND
  480.         | OROR
  481.         | ARROW
  482.         | ARROWstar
  483.         | '.'
  484.         | DOTstar
  485.         | ICR
  486.         | DECR
  487.         | LE
  488.         | GE
  489.         | EQ
  490.         | NE
  491.         | assignment_operator
  492.         | '(' ')'
  493.         | '[' ']'
  494.         | NEW
  495.         | DELETE
  496.         | ','
  497.         ;
  498.  
  499.  
  500.     /* The following production for type_qualifier_list was specially 
  501.     placed BEFORE the definition of postfix_expression to  resolve  a 
  502.     reduce-reduce    conflict    set    correctly.    Note   that   a 
  503.     type_qualifier_list is only used  in  a  declaration,  whereas  a 
  504.     postfix_expression is clearly an example of an expression.  Hence 
  505.     we  are helping with the "if it can be a declaration, then it is" 
  506.     rule.  The reduce conflicts are on ')', ',' and '='.  Do not move 
  507.     the following productions */
  508.  
  509. type_qualifier_list_opt:
  510.         /* Nothing */
  511.         | type_qualifier_list
  512.         ;
  513.  
  514.  
  515.     /*  Note  that  the next set of productions in this grammar gives 
  516.     post-increment a higher precedence that pre-increment.   This  is 
  517.     not  clearly  stated  in  the  C++  Reference manual, and is only 
  518.     implied by the grammar in the ANSI C Standard. */
  519.  
  520.     /* I *DON'T* use  argument_expression_list_opt  to  simplify  the 
  521.     grammar  shown  below.   I am deliberately deferring any decision 
  522.     until    *after*     the     closing     paren,     and     using 
  523.     "argument_expression_list_opt" would commit prematurely.  This is 
  524.     critical to proper conflict resolution. */
  525.  
  526.     /*  The  {}  in  the following rules allow the parser to tell the 
  527.     lexer to search for the member name  in  the  appropriate  scope, 
  528.     much the way the CLCL operator works.*/
  529.  
  530. postfix_expression:
  531.         primary_expression
  532.         | postfix_expression '[' comma_expression ']'
  533.         | postfix_expression '(' ')'
  534.         | postfix_expression '(' argument_expression_list ')'
  535.         | postfix_expression {} '.'   member_name
  536.         | postfix_expression {} ARROW member_name
  537.         | postfix_expression ICR
  538.         | postfix_expression DECR
  539.  
  540.                 /* The next 4 rules are the source of cast ambiguity */
  541.         | TYPEDEFname                  '(' ')'
  542.         | global_or_scoped_typedefname '(' ')'
  543.         | TYPEDEFname                  '(' argument_expression_list ')'
  544.         | global_or_scoped_typedefname '(' argument_expression_list ')'
  545.         | basic_type_name '(' assignment_expression ')'
  546.             /* If the following rule is added to the  grammar,  there 
  547.             will  be 3 additional reduce-reduce conflicts.  They will 
  548.             all be resolved in favor of NOT using the following rule, 
  549.             so no harm will be done.   However,  since  the  rule  is 
  550.             semantically  illegal  we  will  omit  it  until  we  are 
  551.             enhancing the grammar for error recovery */
  552. /*      | basic_type_name '(' ')'  /* Illegal: no such constructor*/
  553.         ;
  554.  
  555.  
  556.     /* The last two productions in the next set are questionable, but 
  557.     do not induce any conflicts.  I need to ask X3J16 :  Having  them 
  558.     means that we have complex member function deletes like:
  559.  
  560.           const unsigned int :: ~ const unsigned int
  561.     */
  562.  
  563. member_name:
  564.         scope_opt_identifier
  565.         | scope_opt_complex_name
  566.         | basic_type_name CLCL '~' basic_type_name  /* C++, not ANSI C */
  567.  
  568.         | declaration_qualifier_list  CLCL '~'   declaration_qualifier_list
  569.         | type_qualifier_list         CLCL '~'   type_qualifier_list
  570.         ;
  571.  
  572. argument_expression_list:
  573.         assignment_expression
  574.         | argument_expression_list ',' assignment_expression
  575.         ;
  576.  
  577. unary_expression:
  578.         postfix_expression
  579.         | ICR  unary_expression
  580.         | DECR unary_expression
  581.         | asterisk_or_ampersand cast_expression
  582.         | '-'                   cast_expression
  583.         | '+'                   cast_expression
  584.         | '~'                   cast_expression
  585.         | '!'                   cast_expression
  586.         | SIZEOF unary_expression
  587.         | SIZEOF '(' type_name ')'
  588.         | allocation_expression
  589.         ;
  590.  
  591.  
  592.     /* Note that I could have moved the  newstore  productions  to  a 
  593.     lower  precedence  level  than  multiplication  (binary '*'), and 
  594.     lower than bitwise AND (binary '&').  These moves  are  the  nice 
  595.     way  to  disambiguate a trailing unary '*' or '&' at the end of a 
  596.     freestore expression.  Since the freestore expression (with  such 
  597.     a  grammar  and  hence  precedence  given)  can never be the left 
  598.     operand of a binary '*' or '&', the ambiguity would  be  removed. 
  599.     These  problems  really  surface when the binary operators '*' or 
  600.     '&' are overloaded, but this must be syntactically  disambiguated 
  601.     before the semantic checking is performed...  Unfortunately, I am 
  602.     not  creating  the language, only writing a grammar that reflects 
  603.     its specification, and  hence  I  cannot  change  its  precedence 
  604.     assignments.   If  I  had  my  druthers,  I would probably prefer 
  605.     surrounding the type with parens all the time, and  avoiding  the 
  606.     dangling * and & problem all together.*/
  607.  
  608.        /* Following are C++, not ANSI C */
  609. allocation_expression:
  610.         global_opt_scope_opt_operator_new                                    '(' type_name ')'
  611.                 operator_new_initializer_opt
  612.  
  613.         | global_opt_scope_opt_operator_new '(' argument_expression_list ')' '(' type_name ')'
  614.                 operator_new_initializer_opt
  615.  
  616.                 /* next two rules are the source of * and & ambiguities */
  617.         | global_opt_scope_opt_operator_new                                  operator_new_type
  618.         | global_opt_scope_opt_operator_new '(' argument_expression_list ')' operator_new_type
  619.         ;
  620.  
  621.  
  622.        /* Following are C++, not ANSI C */
  623. global_opt_scope_opt_operator_new:
  624.         NEW
  625.         | global_or_scope NEW
  626.         ;
  627.  
  628. operator_new_type:
  629.         type_qualifier_list              operator_new_declarator_opt
  630.                         operator_new_initializer_opt
  631.  
  632.         | non_elaborating_type_specifier operator_new_declarator_opt
  633.                         operator_new_initializer_opt
  634.         ;
  635.  
  636.     
  637.     /*  Right  recursion  is critical in the following productions to 
  638.     avoid a conflict on TYPEDEFname */
  639.  
  640. operator_new_declarator_opt:
  641.         /* Nothing */
  642.         | operator_new_array_declarator
  643.         | asterisk_or_ampersand operator_new_declarator_opt
  644.         | unary_modifier        operator_new_declarator_opt
  645.         ;
  646.  
  647. operator_new_array_declarator:
  648.                                         '['                  ']'
  649.         |                               '[' comma_expression ']'
  650.         | operator_new_array_declarator '[' comma_expression ']'
  651.         ;
  652.  
  653. operator_new_initializer_opt:
  654.         /* Nothing */
  655.         | '('                          ')'
  656.         | '(' argument_expression_list ')'
  657.         ;
  658.  
  659. cast_expression:
  660.         unary_expression
  661.         | '(' type_name ')' cast_expression
  662.         ;
  663.  
  664.  
  665.     /* Following are C++, not ANSI C */
  666. deallocation_expression:
  667.         cast_expression
  668.         | global_opt_scope_opt_delete deallocation_expression
  669.         | global_opt_scope_opt_delete '[' comma_expression ']' deallocation_expression  /* archaic C++, what a concept */
  670.         | global_opt_scope_opt_delete '[' ']' deallocation_expression
  671.         ;
  672.  
  673.  
  674.     /* Following are C++, not ANSI C */
  675. global_opt_scope_opt_delete:
  676.         DELETE
  677.         | global_or_scope DELETE
  678.         ;
  679.  
  680.  
  681.     /* Following are C++, not ANSI C */
  682. point_member_expression:
  683.         deallocation_expression
  684.         | point_member_expression DOTstar  deallocation_expression
  685.         | point_member_expression ARROWstar  deallocation_expression
  686.         ;
  687.  
  688. multiplicative_expression:
  689.         point_member_expression
  690.         | multiplicative_expression '*' point_member_expression
  691.         | multiplicative_expression '/' point_member_expression
  692.         | multiplicative_expression '%' point_member_expression
  693.         ;
  694.  
  695. additive_expression:
  696.         multiplicative_expression
  697.         | additive_expression '+' multiplicative_expression
  698.         | additive_expression '-' multiplicative_expression
  699.         ;
  700.  
  701. shift_expression:
  702.         additive_expression
  703.         | shift_expression LS additive_expression
  704.         | shift_expression RS additive_expression
  705.         ;
  706.  
  707. relational_expression:
  708.         shift_expression
  709.         | relational_expression '<' shift_expression
  710.         | relational_expression '>' shift_expression
  711.         | relational_expression LE  shift_expression
  712.         | relational_expression GE  shift_expression
  713.         ;
  714.  
  715. equality_expression:
  716.         relational_expression
  717.         | equality_expression EQ relational_expression
  718.         | equality_expression NE relational_expression
  719.         ;
  720.  
  721. AND_expression:
  722.         equality_expression
  723.         | AND_expression '&' equality_expression
  724.         ;
  725.  
  726. exclusive_OR_expression:
  727.         AND_expression
  728.         | exclusive_OR_expression '^' AND_expression
  729.         ;
  730.  
  731. inclusive_OR_expression:
  732.         exclusive_OR_expression
  733.         | inclusive_OR_expression '|' exclusive_OR_expression
  734.         ;
  735.  
  736. logical_AND_expression:
  737.         inclusive_OR_expression
  738.         | logical_AND_expression ANDAND inclusive_OR_expression
  739.         ;
  740.  
  741. logical_OR_expression:
  742.         logical_AND_expression
  743.         | logical_OR_expression OROR logical_AND_expression
  744.         ;
  745.  
  746. conditional_expression:
  747.         logical_OR_expression
  748.  
  749.         | logical_OR_expression '?' comma_expression ':'
  750.                 conditional_expression
  751.         ;
  752.  
  753. assignment_expression:
  754.         conditional_expression
  755.         | unary_expression assignment_operator assignment_expression
  756.         ;
  757.  
  758. assignment_operator:
  759.         '='
  760.         | MULTassign
  761.         | DIVassign
  762.         | MODassign
  763.         | PLUSassign
  764.         | MINUSassign
  765.         | LSassign
  766.         | RSassign
  767.         | ANDassign
  768.         | ERassign
  769.         | ORassign
  770.         ;
  771.  
  772. comma_expression:
  773.         assignment_expression
  774.         | comma_expression ',' assignment_expression
  775.         ;
  776.  
  777. constant_expression:
  778.         conditional_expression
  779.         ;
  780.  
  781.  
  782.     /* The following was used for clarity */
  783. comma_expression_opt:
  784.         /* Nothing */
  785.         | comma_expression
  786.         ;
  787.  
  788.  
  789. /******************************* DECLARATIONS *********************************/
  790.  
  791.  
  792.     /*  The  following are notably different from the ANSI C Standard 
  793.     specified grammar, but  are  present  in  my  ANSI  C  compatible 
  794.     grammar.  The changes were made to disambiguate typedefs presence 
  795.     in   declaration_specifiers   (vs.    in   the   declarator   for 
  796.     redefinition); to allow struct/union/enum/class tag  declarations 
  797.     without  declarators,  and  to  better  reflect  the  parsing  of 
  798.     declarations    (declarators    must     be     combined     with 
  799.     declaration_specifiers  ASAP, so that they can immediately become 
  800.     visible in the current scope). */
  801.  
  802. declaration:
  803.         declaring_list ';'
  804.         | default_declaring_list ';'
  805.         | sue_declaration_specifier ';' { /* this is constraint error, as it
  806.                                         includes a storage class!?!*/ }
  807.         | sue_type_specifier ';'
  808.         | sue_type_specifier_elaboration ';'
  809.         ;
  810.  
  811.  
  812.     /* Note that if a typedef were  redeclared,  then  a  declaration 
  813.     specifier  must be supplied (re: ANSI C spec).  The following are 
  814.     declarations wherein no declaration_specifier  is  supplied,  and 
  815.     hence the 'default' must be used.  An example of this is
  816.  
  817.         const a;
  818.  
  819.     which by default, is the same as:
  820.  
  821.         const int a;
  822.  
  823.     `a' must NOT be a typedef in the above example. */
  824.  
  825.  
  826.     /*  The  presence of `{}' in the following rules indicates points 
  827.     at which the symbol table MUST be updated so that  the  tokenizer 
  828.     can  IMMEDIATELY  continue  to  maintain  the  proper distinction 
  829.     between a TYPEDEFname and an IDENTIFIER. */
  830.  
  831. default_declaring_list:  /* Can't  redeclare typedef names */
  832.         declaration_qualifier_list   identifier_declarator {} initializer_opt
  833.         | type_qualifier_list        identifier_declarator {} initializer_opt
  834.         | default_declaring_list ',' identifier_declarator {} initializer_opt
  835.  
  836.         | declaration_qualifier_list constructed_identifier_declarator
  837.         | type_qualifier_list        constructed_identifier_declarator
  838.         | default_declaring_list ',' constructed_identifier_declarator
  839.         ;
  840.  
  841.  
  842.     /* Note how type_qualifier_list is  NOT  used  in  the  following 
  843.     productions.    Qualifiers   are   NOT   sufficient  to  redefine 
  844.     typedef-names (as prescribed by the ANSI C standard).*/
  845.  
  846. declaring_list:
  847.         declaration_specifier          declarator {} initializer_opt
  848.         | type_specifier               declarator {} initializer_opt
  849.         | basic_type_name              declarator {} initializer_opt
  850.         | TYPEDEFname                  declarator {} initializer_opt
  851.         | global_or_scoped_typedefname declarator {} initializer_opt
  852.         | declaring_list ','           declarator {} initializer_opt
  853.  
  854.         | declaration_specifier        constructed_declarator
  855.         | type_specifier               constructed_declarator
  856.         | basic_type_name              constructed_declarator
  857.         | TYPEDEFname                  constructed_declarator
  858.         | global_or_scoped_typedefname constructed_declarator
  859.         | declaring_list ','           constructed_declarator
  860.         ;
  861.  
  862.  
  863.     /* Declarators with  parenthesized  initializers  present  a  big 
  864.     problem.  Typically  a  declarator  that looks like: "*a(...)" is 
  865.     supposed to bind FIRST to the "(...)", and then to the "*".  This 
  866.     binding  presumes  that  the  "(...)" stuff is a prototype.  With 
  867.     constructed declarators, we must (officially) finish the  binding 
  868.     to the "*" (finishing forming a good declarator) and THEN connect 
  869.     with  the argument list. Unfortunately, by the time we realize it 
  870.     is an argument list (and not a  prototype)  we  have  pushed  the 
  871.     separate  declarator  tokens  "*"  and  "a"  onto  the yacc stack 
  872.     WITHOUT combining them. The solution is to use odd productions to 
  873.     carry  the  incomplete  declarator  along  with   the   "argument 
  874.     expression  list" back up the yacc stack.  We would then actually 
  875.     instantiate the symbol table after we have  fully  decorated  the 
  876.     symbol  with all the leading "*" stuff.  Actually, since we don't 
  877.     have all the type information in one spot till  we  reduce  to  a 
  878.     declaring_list,  this delay is not a problem.  Note that ordinary 
  879.     initializers REQUIRE (ANSI C Standard) that the symbol be  placed 
  880.     into  the symbol table BEFORE its initializer is read, but in the 
  881.     case of parenthesized initializers,  this  is  not  possible  (we 
  882.     don't  even  know  we  have  an  initializer till have passed the 
  883.     opening "(". ) */
  884.  
  885. constructed_declarator:
  886.         nonunary_constructed_identifier_declarator
  887.         | constructed_paren_typedef_declarator
  888.         | simple_paren_typedef_declarator '(' argument_expression_list ')'
  889.  
  890.         | simple_paren_typedef_declarator postfixing_abstract_declarator
  891.                                           '(' argument_expression_list ')'  /* constraint error */
  892.  
  893.         | constructed_parameter_typedef_declarator
  894.         | asterisk_or_ampersand constructed_declarator
  895.         | unary_modifier        constructed_declarator
  896.         ;
  897.  
  898. constructed_paren_typedef_declarator:
  899.         '(' paren_typedef_declarator ')'
  900.                     '(' argument_expression_list ')'
  901.  
  902.         | '(' paren_typedef_declarator ')' postfixing_abstract_declarator
  903.                    '(' argument_expression_list ')'
  904.  
  905.         | '(' simple_paren_typedef_declarator postfixing_abstract_declarator ')'
  906.                    '(' argument_expression_list ')'
  907.  
  908.         | '(' TYPEDEFname postfixing_abstract_declarator ')'
  909.                    '(' argument_expression_list ')'
  910.         ;
  911.  
  912.  
  913. constructed_parameter_typedef_declarator:
  914.         TYPEDEFname    '(' argument_expression_list ')'
  915.  
  916.         | TYPEDEFname  postfixing_abstract_declarator
  917.                        '(' argument_expression_list ')'  /* constraint error */
  918.  
  919.         | '(' clean_typedef_declarator ')'
  920.                        '(' argument_expression_list ')'
  921.  
  922.         | '(' clean_typedef_declarator ')'  postfixing_abstract_declarator
  923.                        '(' argument_expression_list ')'
  924.         ;
  925.  
  926.  
  927. constructed_identifier_declarator:
  928.         nonunary_constructed_identifier_declarator
  929.         | asterisk_or_ampersand constructed_identifier_declarator
  930.         | unary_modifier        constructed_identifier_declarator
  931.         ;
  932.  
  933.  
  934.     /* The following are restricted to NOT  begin  with  any  pointer 
  935.     operators.   This  includes both "*" and "T::*" modifiers.  Aside 
  936.     from  this  restriction,   the   following   would   have   been: 
  937.     identifier_declarator '(' argument_expression_list ')' */
  938.  
  939. nonunary_constructed_identifier_declarator:
  940.         paren_identifier_declarator   '(' argument_expression_list ')'
  941.  
  942.         | paren_identifier_declarator postfixing_abstract_declarator
  943.                        '(' argument_expression_list ')'  /* constraint error*/
  944.  
  945.         | '(' unary_identifier_declarator ')'
  946.                        '(' argument_expression_list ')'
  947.  
  948.         | '(' unary_identifier_declarator ')' postfixing_abstract_declarator
  949.                        '(' argument_expression_list ')'
  950.         ;
  951.  
  952.  
  953. declaration_specifier:
  954.         basic_declaration_specifier          /* Arithmetic or void */
  955.         | sue_declaration_specifier          /* struct/union/enum/class */
  956.         | typedef_declaration_specifier      /* typedef*/
  957.         ;
  958.  
  959. type_specifier:
  960.         basic_type_specifier                 /* Arithmetic or void */
  961.         | sue_type_specifier                 /* Struct/Union/Enum/Class */
  962.         | sue_type_specifier_elaboration     /* elaborated Struct/Union/Enum/Class */
  963.         | typedef_type_specifier             /* Typedef */
  964.         ;
  965.  
  966. declaration_qualifier_list:  /* storage class and optional const/volatile */
  967.         storage_class
  968.         | type_qualifier_list storage_class
  969.         | declaration_qualifier_list declaration_qualifier
  970.         ;
  971.  
  972. type_qualifier_list:
  973.         type_qualifier
  974.         | type_qualifier_list type_qualifier
  975.         ;
  976.  
  977. declaration_qualifier:
  978.         storage_class
  979.         | type_qualifier                  /* const or volatile */
  980.         ;
  981.  
  982. type_qualifier:
  983.         CONST
  984.         | VOLATILE
  985.         ;
  986.  
  987. basic_declaration_specifier:      /*Storage Class+Arithmetic or void*/
  988.         declaration_qualifier_list    basic_type_name
  989.         | basic_type_specifier        storage_class
  990.         | basic_type_name             storage_class
  991.         | basic_declaration_specifier declaration_qualifier
  992.         | basic_declaration_specifier basic_type_name
  993.         ;
  994.  
  995. basic_type_specifier:
  996.         type_qualifier_list    basic_type_name /* Arithmetic or void */
  997.         | basic_type_name      basic_type_name
  998.         | basic_type_name      type_qualifier
  999.         | basic_type_specifier type_qualifier
  1000.         | basic_type_specifier basic_type_name
  1001.         ;
  1002.  
  1003. sue_declaration_specifier:          /* Storage Class + struct/union/enum/class */
  1004.         declaration_qualifier_list       elaborated_type_name
  1005.         | declaration_qualifier_list     elaborated_type_name_elaboration
  1006.         | sue_type_specifier             storage_class
  1007.         | sue_type_specifier_elaboration storage_class
  1008.         | sue_declaration_specifier      declaration_qualifier
  1009.         ;
  1010.  
  1011. sue_type_specifier_elaboration:
  1012.         elaborated_type_name_elaboration     /* elaborated struct/union/enum/class */
  1013.         | type_qualifier_list elaborated_type_name_elaboration
  1014.         | sue_type_specifier_elaboration type_qualifier
  1015.         ;
  1016.  
  1017. sue_type_specifier:
  1018.         elaborated_type_name              /* struct/union/enum/class */
  1019.         | type_qualifier_list elaborated_type_name
  1020.         | sue_type_specifier type_qualifier
  1021.         ;
  1022.  
  1023. typedef_declaration_specifier:       /*Storage Class + typedef types */
  1024.         declaration_qualifier_list   TYPEDEFname
  1025.         | declaration_qualifier_list global_or_scoped_typedefname
  1026.  
  1027.         | typedef_type_specifier       storage_class
  1028.         | TYPEDEFname                  storage_class
  1029.         | global_or_scoped_typedefname storage_class
  1030.  
  1031.         | typedef_declaration_specifier declaration_qualifier
  1032.         ;
  1033.  
  1034. typedef_type_specifier:              /* typedef types */
  1035.         type_qualifier_list      TYPEDEFname
  1036.         | type_qualifier_list    global_or_scoped_typedefname
  1037.  
  1038.         | TYPEDEFname                  type_qualifier
  1039.         | global_or_scoped_typedefname type_qualifier
  1040.  
  1041.         | typedef_type_specifier type_qualifier
  1042.         ;
  1043.  
  1044.  
  1045. /*  There  are  really  several distinct sets of storage_classes. The 
  1046. sets vary depending on whether the declaration is at file scope, is a 
  1047. declaration within a struct/class, is within a function body, or in a 
  1048. function declaration/definition (prototype  parameter  declarations).  
  1049. They   are   grouped  here  to  simplify  the  grammar,  and  can  be 
  1050. semantically checked.  Note that this  approach  tends  to  ease  the 
  1051. syntactic restrictions in the grammar slightly, but allows for future 
  1052. language  development,  and tends to provide superior diagnostics and 
  1053. error recovery (i_e.: a syntax error does not disrupt the parse).
  1054.  
  1055.  
  1056.                 File    File    Member  Member  Local   Local  Formal
  1057.                 Var     Funct   Var     Funct   Var     Funct  Params
  1058. TYPEDEF         x       x       x       x       x       x
  1059. EXTERN          x       x                       x       x
  1060. STATIC          x       x       x       x       x
  1061. AUTO                                            x              x
  1062. REGISTER                                        x              x
  1063. FRIEND                                  x
  1064. OVERLOAD                x               x               x
  1065. INLINE                  x               x               x
  1066. VIRTUAL                                 x               x
  1067. */
  1068.  
  1069. storage_class:
  1070.         EXTERN
  1071.         | TYPEDEF
  1072.         | STATIC
  1073.         | AUTO
  1074.         | REGISTER
  1075.         | FRIEND   /* C++, not ANSI C */
  1076.         | OVERLOAD /* C++, not ANSI C */
  1077.         | INLINE   /* C++, not ANSI C */
  1078.         | VIRTUAL  /* C++, not ANSI C */
  1079.         ;
  1080.  
  1081. basic_type_name:
  1082.         INT
  1083.         | CHAR
  1084.         | SHORT
  1085.         | LONG
  1086.         | FLOAT
  1087.         | DOUBLE
  1088.         | SIGNED
  1089.         | UNSIGNED
  1090.         | VOID
  1091.         ;
  1092.  
  1093. elaborated_type_name_elaboration:
  1094.         aggregate_name_elaboration
  1095.         | enum_name_elaboration
  1096.         ;
  1097.  
  1098. elaborated_type_name:
  1099.         aggregate_name
  1100.         | enum_name
  1101.         ;
  1102.  
  1103.  
  1104.     /* Since the expression "new type_name" MIGHT use  an  elaborated 
  1105.     type  and a derivation, it MIGHT have a ':'.  This fact conflicts 
  1106.     with the requirement that a new expression can be placed  between 
  1107.     a '?' and a ':' in a conditional expression (at least it confuses 
  1108.     LR(1)   parsers).   Hence   the   aggregate_name_elaboration   is 
  1109.     responsible for a series of SR conflicts on ':'.*/
  1110.  
  1111.     /* The intermediate actions {}  represent  points  at  which  the 
  1112.     database  of  typedef  names  must  be  updated  in C++.  This is 
  1113.     critical to the lexer, which must begin to tokenize based on this 
  1114.     new information. */
  1115.  
  1116. aggregate_name_elaboration:
  1117.         aggregate_name derivation_opt  '{' member_declaration_list_opt '}'
  1118.         | aggregate_key derivation_opt '{' member_declaration_list_opt '}'
  1119.         ;
  1120.  
  1121.  
  1122.     /* We distinguish between the above, which  support  elaboration, 
  1123.     and  this  set  of  productions  so  that  we can provide special 
  1124.     declaration specifiers for operator_new_type, and for  conversion 
  1125.     functions.  Note that without this restriction a large variety of 
  1126.     conflicts  appear  when  processing  operator_new and conversions 
  1127.     operators (which can be  followed  by  a  ':'  in  a  ternary  ?: 
  1128.     expression) */
  1129.  
  1130.     /*  Note that at the end of each of the following rules we should 
  1131.     be sure that the tag name is  in,  or  placed  in  the  indicated 
  1132.     scope.   If  no  scope  is  specified, then we must add it to our 
  1133.     current scope IFF it cannot  be  found  in  an  external  lexical 
  1134.     scope. */
  1135.  
  1136. aggregate_name:
  1137.                              aggregate_key tag_name
  1138.         | global_scope scope aggregate_key tag_name
  1139.         | global_scope       aggregate_key tag_name
  1140.         | scope              aggregate_key tag_name
  1141.         ;
  1142.  
  1143. derivation_opt:
  1144.         /* nothing */
  1145.         | ':' derivation_list
  1146.         ;
  1147.  
  1148. derivation_list:
  1149.         parent_class
  1150.         | derivation_list ',' parent_class
  1151.         ;
  1152.  
  1153. parent_class:
  1154.                                        global_opt_scope_opt_typedefname
  1155.         | VIRTUAL access_specifier_opt global_opt_scope_opt_typedefname
  1156.         | access_specifier virtual_opt global_opt_scope_opt_typedefname
  1157.         ;
  1158.  
  1159. virtual_opt:
  1160.         /* nothing */
  1161.         | VIRTUAL
  1162.         ;
  1163.  
  1164. access_specifier_opt:
  1165.         /* nothing */
  1166.         | access_specifier
  1167.         ;
  1168.  
  1169. access_specifier:
  1170.         PUBLIC
  1171.         | PRIVATE
  1172.         | PROTECTED
  1173.         ;
  1174.  
  1175. aggregate_key:
  1176.         STRUCT
  1177.         | UNION
  1178.         | CLASS /* C++, not ANSI C */
  1179.         ;
  1180.  
  1181.  
  1182.     /* Note that an empty list is ONLY allowed under C++. The grammar 
  1183.     can  be modified so that this stands out.  The trick is to define 
  1184.     member_declaration_list, and have that referenced for non-trivial 
  1185.     lists. */
  1186.  
  1187. member_declaration_list_opt:
  1188.         /* nothing */
  1189.         | member_declaration_list_opt member_declaration
  1190.         ;
  1191.  
  1192. member_declaration:
  1193.         member_declaring_list ';'
  1194.         | member_default_declaring_list ';'
  1195.  
  1196.         | access_specifier ':'               /* C++, not ANSI C */
  1197.  
  1198.         | new_function_definition            /* C++, not ANSI C */
  1199.         | constructor_function_in_class      /* C++, not ANSI C */
  1200.  
  1201.         | sue_type_specifier             ';' /* C++, not ANSI C */
  1202.         | sue_type_specifier_elaboration ';' /* C++, not ANSI C */
  1203.         | identifier_declarator          ';' /* C++, not ANSI C
  1204.                                                 access modification
  1205.                                                 conversion functions,
  1206.                                                 unscoped destructors */
  1207.  
  1208.         | typedef_declaration_specifier ';' /* friend T */       /* C++, not ANSI C */
  1209.         | sue_declaration_specifier ';'     /* friend class C*/  /* C++, not ANSI C */
  1210.         ;
  1211.  
  1212. member_default_declaring_list:        /* doesn't redeclare typedef*/
  1213.         type_qualifier_list
  1214.                 identifier_declarator member_pure_opt
  1215.  
  1216.         | declaration_qualifier_list
  1217.                 identifier_declarator member_pure_opt /* C++, not ANSI C */
  1218.  
  1219.         | member_default_declaring_list ','
  1220.                 identifier_declarator member_pure_opt
  1221.  
  1222.         | type_qualifier_list                bit_field_identifier_declarator
  1223.         | declaration_qualifier_list         bit_field_identifier_declarator /* C++, not ANSI C */
  1224.         | member_default_declaring_list ','  bit_field_identifier_declarator
  1225.         ;
  1226.  
  1227.  
  1228.     /* There is a conflict when "struct A" is used as  a  declaration 
  1229.     specifier,  and  there  is a chance that a bit field name will be 
  1230.     provided.  To fix this syntactically would require distinguishing 
  1231.     non_elaborating_declaration_specifiers   the   way   I    handled 
  1232.     non_elaborating_type_specifiers.   I   think  this  should  be  a 
  1233.     constraint error anyway :-). */
  1234.  
  1235. member_declaring_list:        /* Can possibly redeclare typedefs */
  1236.         type_specifier                 declarator member_pure_opt
  1237.         | basic_type_name              declarator member_pure_opt
  1238.  
  1239.         | global_or_scoped_typedefname declarator member_pure_opt
  1240.         | member_conflict_declaring_item
  1241.         | member_declaring_list ','    declarator member_pure_opt
  1242.  
  1243.         | type_specifier                bit_field_declarator
  1244.         | basic_type_name               bit_field_declarator
  1245.         | TYPEDEFname                   bit_field_declarator
  1246.         | global_or_scoped_typedefname  bit_field_declarator
  1247.         | declaration_specifier         bit_field_declarator /* constraint violation: storage class used */
  1248.         | member_declaring_list ','     bit_field_declarator
  1249.         ;
  1250.  
  1251.  
  1252.     /* The following conflict with constructors-
  1253.       member_conflict_declaring_item:
  1254.         TYPEDEFname             declarator member_pure_opt
  1255.         | declaration_specifier declarator member_pure_opt /* C++, not ANSI C * /
  1256.         ;
  1257.     so we inline expand declarator to get the following productions...
  1258.     */
  1259. member_conflict_declaring_item:
  1260.         TYPEDEFname             identifier_declarator            member_pure_opt
  1261.         | TYPEDEFname           parameter_typedef_declarator     member_pure_opt
  1262.         | TYPEDEFname           simple_paren_typedef_declarator  member_pure_opt
  1263.  
  1264.         | declaration_specifier identifier_declarator            member_pure_opt
  1265.         | declaration_specifier parameter_typedef_declarator     member_pure_opt
  1266.         | declaration_specifier simple_paren_typedef_declarator  member_pure_opt
  1267.  
  1268.         | member_conflict_paren_declaring_item
  1269.         ;
  1270.  
  1271.  
  1272.     /* The following still conflicts with constructors-
  1273.       member_conflict_paren_declaring_item:
  1274.         TYPEDEFname             paren_typedef_declarator     member_pure_opt
  1275.         | declaration_specifier paren_typedef_declarator     member_pure_opt
  1276.         ;
  1277.     so paren_typedef_declarator is expanded inline to get...*/
  1278.  
  1279. member_conflict_paren_declaring_item:
  1280.         TYPEDEFname   asterisk_or_ampersand
  1281.                 '(' simple_paren_typedef_declarator ')' member_pure_opt
  1282.         | TYPEDEFname unary_modifier
  1283.                 '(' simple_paren_typedef_declarator ')' member_pure_opt
  1284.         | TYPEDEFname asterisk_or_ampersand
  1285.                 '(' TYPEDEFname ')'                     member_pure_opt
  1286.         | TYPEDEFname unary_modifier
  1287.                 '(' TYPEDEFname ')'                     member_pure_opt
  1288.         | TYPEDEFname asterisk_or_ampersand
  1289.                  paren_typedef_declarator               member_pure_opt
  1290.         | TYPEDEFname unary_modifier
  1291.                  paren_typedef_declarator               member_pure_opt
  1292.  
  1293.         | declaration_specifier asterisk_or_ampersand
  1294.                 '(' simple_paren_typedef_declarator ')' member_pure_opt
  1295.         | declaration_specifier unary_modifier
  1296.                 '(' simple_paren_typedef_declarator ')' member_pure_opt
  1297.         | declaration_specifier asterisk_or_ampersand
  1298.                 '(' TYPEDEFname ')'                     member_pure_opt
  1299.         | declaration_specifier unary_modifier
  1300.                 '(' TYPEDEFname ')'                     member_pure_opt
  1301.         | declaration_specifier asterisk_or_ampersand
  1302.                 paren_typedef_declarator                member_pure_opt
  1303.         | declaration_specifier unary_modifier
  1304.                 paren_typedef_declarator                member_pure_opt
  1305.  
  1306.         | member_conflict_paren_postfix_declaring_item
  1307.         ;
  1308.  
  1309.  
  1310.     /* but we still have the following conflicts with constructors-
  1311.    member_conflict_paren_postfix_declaring_item:
  1312.       TYPEDEFname             postfix_paren_typedef_declarator member_pure_opt
  1313.       | declaration_specifier postfix_paren_typedef_declarator member_pure_opt
  1314.       ;
  1315.     so we expand paren_postfix_typedef inline and get...*/
  1316.  
  1317. member_conflict_paren_postfix_declaring_item:
  1318.         TYPEDEFname     '(' paren_typedef_declarator ')'
  1319.                                                            member_pure_opt
  1320.         | TYPEDEFname   '(' simple_paren_typedef_declarator
  1321.                         postfixing_abstract_declarator ')' member_pure_opt
  1322.         | TYPEDEFname   '(' TYPEDEFname
  1323.                         postfixing_abstract_declarator ')' member_pure_opt
  1324.         | TYPEDEFname   '(' paren_typedef_declarator ')'
  1325.                         postfixing_abstract_declarator     member_pure_opt
  1326.  
  1327.         | declaration_specifier '(' paren_typedef_declarator ')'
  1328.                                                            member_pure_opt
  1329.         | declaration_specifier '(' simple_paren_typedef_declarator
  1330.                         postfixing_abstract_declarator ')' member_pure_opt
  1331.         | declaration_specifier '(' TYPEDEFname
  1332.                         postfixing_abstract_declarator ')' member_pure_opt
  1333.         | declaration_specifier '(' paren_typedef_declarator ')'
  1334.                         postfixing_abstract_declarator     member_pure_opt
  1335.         ;
  1336.     /* ...and we are done.  Now all  the  conflicts  appear  on  ';', 
  1337.     which can be semantically evaluated/disambiguated */
  1338.  
  1339.  
  1340. member_pure_opt:
  1341.         /* nothing */
  1342.         | '=' OCTALconstant /* C++, not ANSI C */ /* Pure function*/
  1343.         ;
  1344.  
  1345.  
  1346.     /*  Note  that  bit  field  names, where redefining TYPEDEFnames, 
  1347.     cannot be parenthesized in C++ (due to  ambiguities),  and  hence 
  1348.     this  part of the grammar is simpler than ANSI C. :-) The problem 
  1349.     occurs because:
  1350.  
  1351.          TYPEDEFname ( TYPEDEFname) : .....
  1352.  
  1353.     doesn't look like a bit field, rather it looks like a constructor 
  1354.     definition! */
  1355.  
  1356. bit_field_declarator:
  1357.         bit_field_identifier_declarator
  1358.         | TYPEDEFname {} ':' constant_expression
  1359.         ;
  1360.  
  1361.  
  1362.     /* The actions taken in the "{}" above and below are intended  to 
  1363.     allow  the  symbol  table  to  be  updated when the declarator is 
  1364.     complete.  It is critical for code like:
  1365.  
  1366.             foo : sizeof(foo + 1);
  1367.     */
  1368.  
  1369. bit_field_identifier_declarator:
  1370.                                    ':' constant_expression
  1371.         | identifier_declarator {} ':' constant_expression
  1372.         ;
  1373.  
  1374. enum_name_elaboration:
  1375.         global_opt_scope_opt_enum_key '{' enumerator_list '}'
  1376.         | enum_name                   '{' enumerator_list '}'
  1377.         ;
  1378.  
  1379.  
  1380.     /* As with structures, the distinction between "elaborating"  and 
  1381.     "non-elaborating"  enum  types  is  maintained.  In actuality, it 
  1382.     probably does not cause much in the way of conflicts, since a ':' 
  1383.     is not allowed.  For symmetry, we maintain the distinction.   The 
  1384.     {}  actions are intended to allow the symbol table to be updated.  
  1385.     These updates are significant to code such as:
  1386.  
  1387.         enum A { first=sizeof(A)};
  1388.     */
  1389.  
  1390. enum_name:
  1391.         global_opt_scope_opt_enum_key tag_name
  1392.         ;
  1393.  
  1394. global_opt_scope_opt_enum_key:
  1395.         ENUM
  1396.         | global_or_scope ENUM
  1397.         ;
  1398.  
  1399. enumerator_list:
  1400.         enumerator_list_no_trailing_comma
  1401.         | enumerator_list_no_trailing_comma ',' /* C++, not ANSI C */
  1402.         ;
  1403.  
  1404.  
  1405.     /* Note that we do not need to rush to add an enumerator  to  the 
  1406.     symbol  table  until  *AFTER* the enumerator_value_opt is parsed. 
  1407.     The enumerated value is only in scope  AFTER  its  definition  is 
  1408.     complete.   Hence the following is legal: "enum {a, b=a+10};" but 
  1409.     the following is (assuming no external matching of names) is  not 
  1410.     legal:  "enum {c, d=sizeof(d)};" ("d" not defined when sizeof was 
  1411.     applied.) This is  notably  contrasted  with  declarators,  which 
  1412.     enter scope as soon as the declarator is complete. */
  1413.  
  1414. enumerator_list_no_trailing_comma:
  1415.         enumerator_name enumerator_value_opt
  1416.         | enumerator_list_no_trailing_comma ',' enumerator_name enumerator_value_opt
  1417.         ;
  1418.  
  1419. enumerator_name:
  1420.         IDENTIFIER
  1421.         | TYPEDEFname
  1422.         ;
  1423.  
  1424. enumerator_value_opt:
  1425.         /* Nothing */
  1426.         | '=' constant_expression
  1427.         ;
  1428.  
  1429.  
  1430.     /*  We special case the lone type_name which has no storage class 
  1431.     (even though it should be an example of  a  parameter_type_list). 
  1432.     This helped to disambiguate type-names in parenthetical casts.*/
  1433.  
  1434. parameter_type_list:
  1435.         '(' ')'                             type_qualifier_list_opt
  1436.         | '(' type_name ')'                 type_qualifier_list_opt
  1437.         | '(' type_name initializer ')'     type_qualifier_list_opt /* C++, not ANSI C */
  1438.         | '(' named_parameter_type_list ')' type_qualifier_list_opt
  1439.         ;
  1440.  
  1441.  
  1442.     /* The following are used in old style function definitions, when 
  1443.     a complex return type includes the "function returning" modifier. 
  1444.     Note  the  subtle  distinction  from  parameter_type_list.  These 
  1445.     parameters are NOT the parameters for the function being defined, 
  1446.     but are simply part of the type definition.  An example would be:
  1447.  
  1448.         int(*f(   a  ))(float) long a; {...}
  1449.  
  1450.     which is equivalent to the full new style definition:
  1451.  
  1452.         int(*f(long a))(float) {...}
  1453.  
  1454.     The   type   list    `(float)'    is    an    example    of    an 
  1455.     old_parameter_type_list.   The  bizarre point here is that an old 
  1456.     function definition declarator can be followed by  a  type  list, 
  1457.     which  can  start  with a qualifier `const'.  This conflicts with 
  1458.     the new syntactic construct for const member  functions!?!  As  a 
  1459.     result,  an  old  style function definition cannot be used in all 
  1460.     cases for a member function.  */
  1461.  
  1462. old_parameter_type_list:
  1463.         '(' ')'
  1464.         | '(' type_name ')'
  1465.         | '(' type_name initializer ')'  /* C++, not ANSI C */
  1466.         | '(' named_parameter_type_list ')'
  1467.         ;
  1468.  
  1469. named_parameter_type_list:  /* WARNING: excludes lone type_name*/
  1470.         parameter_list
  1471.         | parameter_list comma_opt_ellipsis
  1472.         | type_name comma_opt_ellipsis
  1473.         | type_name initializer comma_opt_ellipsis  /* C++, not ANSI C */
  1474.         | ELLIPSIS /* C++, not ANSI C */
  1475.         ;
  1476.  
  1477. comma_opt_ellipsis:
  1478.         ELLIPSIS       /* C++, not ANSI C */
  1479.         | ',' ELLIPSIS
  1480.         ;
  1481.  
  1482. parameter_list:
  1483.         non_casting_parameter_declaration
  1484.         | non_casting_parameter_declaration initializer /* C++, not ANSI C */
  1485.         | type_name             ',' parameter_declaration
  1486.         | type_name initializer ',' parameter_declaration  /* C++, not ANSI C */
  1487.         | parameter_list        ',' parameter_declaration
  1488.         ;
  1489.  
  1490.  
  1491.     /* There is some very subtle disambiguation going  on  here.   Do 
  1492.     not be tempted to make further use of the following production in 
  1493.     parameter_list,  or else the conflict count will grow noticeably. 
  1494.     Specifically, the next set  of  rules  has  already  been  inline 
  1495.     expanded for the first parameter in a parameter_list to support a 
  1496.     deferred disambiguation. The subtle disambiguation has to do with 
  1497.     contexts where parameter type lists look like old-style-casts. */
  1498.  
  1499. parameter_declaration:
  1500.         type_name
  1501.         | type_name                         initializer  /* C++, not ANSI C */
  1502.         | non_casting_parameter_declaration
  1503.         | non_casting_parameter_declaration initializer /* C++, not ANSI C */
  1504.         ;
  1505.  
  1506.  
  1507.     /* There is an LR ambiguity between old-style parenthesized casts 
  1508.     and parameter-type-lists.  This tends to happen in contexts where 
  1509.     either  an  expression or a parameter-type-list is possible.  For 
  1510.     example, assume that T is an  externally  declared  type  in  the 
  1511.     code:
  1512.  
  1513.            int (T ((int
  1514.  
  1515.     it might continue:
  1516.  
  1517.            int (T ((int)0));
  1518.  
  1519.     which would make it:
  1520.  
  1521.            (int) (T) (int)0 ;
  1522.  
  1523.     which  is  an  expression,  consisting  of  a  series  of  casts.  
  1524.     Alternatively, it could be:
  1525.  
  1526.            int (T ((int a)));
  1527.  
  1528.     which would make it the redeclaration of T, equivalent to:
  1529.  
  1530.            int T (dummy_name (int a));
  1531.  
  1532.     if we see a type that either has a named variable (in  the  above 
  1533.     case "a"), or a storage class like:
  1534.  
  1535.            int (T ((int register
  1536.  
  1537.     then  we  know  it  can't  be  a cast, and it is "forced" to be a 
  1538.     parameter_list.
  1539.  
  1540.     It is not yet clear that the ANSI C++ committee would  decide  to 
  1541.     place this disambiguation into the syntax, rather than leaving it 
  1542.     as  a  constraint check (i.e., a valid parser would have to parse 
  1543.     everything as though it were  a  parameter  list  (in  these  odd 
  1544.     contexts),  and  then  give an error if is to a following context 
  1545.     (like "0" above) that invalidated this syntax evaluation. */
  1546.  
  1547.     /* One big thing implemented here is that a TYPEDEFname CANNOT be 
  1548.     redeclared when we don't have declaration_specifiers! Notice that 
  1549.     when we do use a TYPEDEFname based declarator, only the "special" 
  1550.     (non-ambiguous  in  this  context)  typedef_declarator  is  used. 
  1551.     Everything else that is "missing" shows up as a type_name. */
  1552.  
  1553. non_casting_parameter_declaration: /*have names or storage classes */
  1554.         declaration_specifier
  1555.         | declaration_specifier abstract_declarator
  1556.         | declaration_specifier identifier_declarator
  1557.         | declaration_specifier parameter_typedef_declarator
  1558.  
  1559.         | declaration_qualifier_list
  1560.         | declaration_qualifier_list abstract_declarator
  1561.         | declaration_qualifier_list identifier_declarator
  1562.  
  1563.         | type_specifier identifier_declarator
  1564.         | type_specifier parameter_typedef_declarator
  1565.  
  1566.         | basic_type_name identifier_declarator
  1567.         | basic_type_name parameter_typedef_declarator
  1568.  
  1569.         | TYPEDEFname                   identifier_declarator
  1570.         | TYPEDEFname                   parameter_typedef_declarator
  1571.  
  1572.         | global_or_scoped_typedefname  identifier_declarator
  1573.         | global_or_scoped_typedefname  parameter_typedef_declarator
  1574.  
  1575.         | type_qualifier_list identifier_declarator
  1576.         ;
  1577.  
  1578. type_name:
  1579.         type_specifier
  1580.         | basic_type_name
  1581.         | TYPEDEFname
  1582.         | global_or_scoped_typedefname
  1583.         | type_qualifier_list
  1584.  
  1585.         | type_specifier               abstract_declarator
  1586.         | basic_type_name              abstract_declarator
  1587.         | TYPEDEFname                  abstract_declarator
  1588.         | global_or_scoped_typedefname abstract_declarator
  1589.         | type_qualifier_list          abstract_declarator
  1590.         ;
  1591.  
  1592. initializer_opt:
  1593.         /* nothing */
  1594.         | initializer
  1595.         ;
  1596.  
  1597. initializer:
  1598.         '=' initializer_group
  1599.         ;
  1600.  
  1601. initializer_group:
  1602.         '{' initializer_list '}'
  1603.         | '{' initializer_list ',' '}'
  1604.         | assignment_expression
  1605.         ;
  1606.  
  1607. initializer_list:
  1608.         initializer_group
  1609.         | initializer_list ',' initializer_group
  1610.         ;
  1611.  
  1612.  
  1613. /*************************** STATEMENTS *******************************/
  1614.  
  1615. statement:
  1616.         labeled_statement
  1617.         | compound_statement
  1618.         | expression_statement
  1619.         | selection_statement
  1620.         | iteration_statement
  1621.         | jump_statement
  1622.         | declaration /* C++, not ANSI C */
  1623.         ;
  1624.  
  1625. labeled_statement:
  1626.         label                      ':' statement
  1627.         | CASE constant_expression ':' statement
  1628.         | DEFAULT                  ':' statement
  1629.         ;
  1630.  
  1631.  
  1632.     /*  I sneak declarations into statement_list to support C++.  The 
  1633.     grammar is a little clumsy this  way,  but  the  violation  of  C 
  1634.     syntax is heavily localized */
  1635.  
  1636. compound_statement:
  1637.         '{' statement_list_opt '}'
  1638.         ;
  1639.  
  1640. declaration_list:
  1641.         declaration
  1642.         | declaration_list declaration
  1643.         ;
  1644.  
  1645. statement_list_opt:
  1646.         /* nothing */
  1647.         | statement_list_opt statement
  1648.         ;
  1649.  
  1650. expression_statement:
  1651.         comma_expression_opt ';'
  1652.         ;
  1653.  
  1654. selection_statement:
  1655.           IF '(' comma_expression ')' statement
  1656.         | IF '(' comma_expression ')' statement ELSE statement
  1657.         | SWITCH '(' comma_expression ')' statement
  1658.         ;
  1659.  
  1660. iteration_statement:
  1661.         WHILE '(' comma_expression_opt ')' statement
  1662.         | DO statement WHILE '(' comma_expression ')' ';'
  1663.  
  1664.         | FOR '(' comma_expression_opt ';' comma_expression_opt ';'
  1665.                 comma_expression_opt ')' statement
  1666.  
  1667.         | FOR '(' declaration        comma_expression_opt ';'
  1668.                 comma_expression_opt ')' statement  /* C++, not ANSI C */
  1669.         ;
  1670.  
  1671. jump_statement:
  1672.         GOTO label                     ';'
  1673.         | CONTINUE                     ';'
  1674.         | BREAK                        ';'
  1675.         | RETURN comma_expression_opt  ';'
  1676.         ;
  1677.  
  1678.  
  1679.     /*  The  following  actions should update the symbol table in the 
  1680.     "label" name space */
  1681.  
  1682. label:
  1683.         IDENTIFIER
  1684.         | TYPEDEFname
  1685.         ;
  1686.  
  1687.  
  1688. /***************************** EXTERNAL DEFINITIONS *****************************/
  1689.  
  1690. translation_unit:
  1691.         /* nothing */
  1692.         | translation_unit external_definition
  1693.         ;
  1694.  
  1695. external_definition:
  1696.         function_declaration                         /* C++, not ANSI C*/
  1697.         | function_definition
  1698.         | declaration
  1699.         | linkage_specifier function_declaration     /* C++, not ANSI C*/
  1700.         | linkage_specifier function_definition      /* C++, not ANSI C*/
  1701.         | linkage_specifier declaration              /* C++, not ANSI C*/
  1702.         | linkage_specifier '{' translation_unit '}' /* C++, not ANSI C*/
  1703.         ;
  1704.  
  1705. linkage_specifier:
  1706.         EXTERN STRINGliteral
  1707.         ;
  1708.  
  1709.  
  1710.     /* Note that declaration_specifiers are left out of the following 
  1711.     function declarations.  Such omission is illegal in ANSI C. It is 
  1712.     sometimes necessary in C++, in instances  where  no  return  type 
  1713.     should be specified (e_g., a conversion operator).*/
  1714.  
  1715. function_declaration:
  1716.         identifier_declarator ';'   /*  semantically  verify  it is a 
  1717.                                     function, and (if ANSI says  it's 
  1718.                                     the  law for C++ also...) that it 
  1719.                                     is something that  can't  have  a 
  1720.                                     return  type  (like  a conversion 
  1721.                                     function, or a destructor */
  1722.  
  1723.         | constructor_function_declaration ';'
  1724.         ;
  1725.  
  1726. function_definition:
  1727.         new_function_definition
  1728.         | old_function_definition
  1729.         | constructor_function_definition
  1730.         ;
  1731.  
  1732.  
  1733.     /* Note that in ANSI C, function definitions *ONLY* are presented 
  1734.     at file scope.  Hence, if there is a typedefname  active,  it  is 
  1735.     illegal  to  redeclare  it  (there  is no enclosing scope at file 
  1736.     scope).
  1737.  
  1738.     In  contrast,  C++  allows   function   definitions   at   struct 
  1739.     elaboration scope, and allows tags that are defined at file scope 
  1740.     (and  hence  look like typedefnames) to be redeclared to function 
  1741.     calls.  Hence several of the rules are "partially C++  only".   I 
  1742.     could  actually  build separate rules for typedef_declarators and 
  1743.     identifier_declarators, and mention that  the  typedef_declarator 
  1744.     rules represent the C++ only features.
  1745.  
  1746.     In  some  sense,  this  is  haggling, as I could/should have left 
  1747.     these as constraints in the ANSI C grammar, rather than as syntax 
  1748.     requirements.  */
  1749.  
  1750. new_function_definition:
  1751.                                        identifier_declarator compound_statement
  1752.         | declaration_specifier                   declarator compound_statement /* partially C++ only */
  1753.         | type_specifier                          declarator compound_statement /* partially C++ only */
  1754.         | basic_type_name                         declarator compound_statement /* partially C++ only */
  1755.         | TYPEDEFname                             declarator compound_statement /* partially C++ only */
  1756.         | global_or_scoped_typedefname            declarator compound_statement /* partially C++ only */
  1757.         | declaration_qualifier_list   identifier_declarator compound_statement
  1758.         | type_qualifier_list          identifier_declarator compound_statement
  1759.         ;
  1760.  
  1761.  
  1762.     /* Note that I do not support redeclaration of TYPEDEFnames  into 
  1763.     function  names  as I did in new_function_definitions (see note). 
  1764.     Perhaps I should do it, but for now, ignore the issue. Note  that 
  1765.     this  is  a  non-problem  with  ANSI  C,  as  tag  names  are not 
  1766.     considered TYPEDEFnames. */
  1767.  
  1768. old_function_definition:
  1769.                                        old_function_declarator {} old_function_body
  1770.         | declaration_specifier        old_function_declarator {} old_function_body
  1771.         | type_specifier               old_function_declarator {} old_function_body
  1772.         | basic_type_name              old_function_declarator {} old_function_body
  1773.         | TYPEDEFname                  old_function_declarator {} old_function_body
  1774.         | global_or_scoped_typedefname old_function_declarator {} old_function_body
  1775.         | declaration_qualifier_list   old_function_declarator {} old_function_body
  1776.         | type_qualifier_list          old_function_declarator {} old_function_body
  1777.         ;
  1778.  
  1779. old_function_body:
  1780.         declaration_list compound_statement
  1781.         | compound_statement
  1782.         ;
  1783.  
  1784.  
  1785.     /*    Verify    via    constraints     that     the     following 
  1786.         declaration_specifier           is          really          a 
  1787.         typedef_declaration_specifier, consisting of:
  1788.  
  1789.         ... TYPEDEFname :: TYPEDEFname
  1790.  
  1791.     optionally *preceded* by a "inline" keyword.   Use  care  not  to 
  1792.     support "inline" as a postfix!
  1793.  
  1794.     Similarly, the global_or_scoped_typedefname must be:
  1795.  
  1796.         ... TYPEDEFname :: TYPEDEFname
  1797.  
  1798.     with matching names at the end of the list.
  1799.  
  1800.     We  use the more general form to prevent a syntax conflict with a 
  1801.     typical    function    definition    (which    won't    have    a 
  1802.     constructor_init_list) */
  1803.  
  1804. constructor_function_definition:
  1805.         global_or_scoped_typedefname parameter_type_list
  1806.                      constructor_init_list_opt compound_statement
  1807.  
  1808.         | declaration_specifier      parameter_type_list
  1809.                      constructor_init_list_opt compound_statement
  1810.         ;
  1811.  
  1812.  
  1813.     /*  Same  comments  as  seen  for constructor_function_definition 
  1814.     apply here */
  1815.  
  1816. constructor_function_declaration:
  1817.         global_or_scoped_typedefname parameter_type_list  /* wasteful redeclaration; used for friend decls.  */
  1818.  
  1819.         | declaration_specifier      parameter_type_list  /* request to inline, no definition */
  1820.         ;
  1821.  
  1822.  
  1823.     /* The following use of declaration_specifiers are made to  allow 
  1824.     for  a TYPEDEFname preceded by an INLINE modifier. This fact must 
  1825.     be verified semantically.  It should also be  verified  that  the 
  1826.     TYPEDEFname  is  ACTUALLY  the  class name being elaborated. Note 
  1827.     that we could break out typedef_declaration_specifier from within 
  1828.     declaration_specifier, and we  might  narrow  down  the  conflict 
  1829.     region a bit. A second alternative (to what is done) for cleaning 
  1830.     up  this  stuff  is  to  let the tokenizer specially identify the 
  1831.     current class being elaborated as a special token, and not just a 
  1832.     typedefname. Unfortunately, things would get very  confusing  for 
  1833.     the  lexer,  as  we may pop into enclosed tag elaboration scopes; 
  1834.     into function definitions; or into both recursively! */
  1835.  
  1836.     /* I should make the following  rules  easier  to  annotate  with 
  1837.     scope  entry  and exit actions.  Note how hard it is to establish 
  1838.     the scope when you don't even know what the decl_spec is!! It can 
  1839.     be done with $-1 hacking, but I should not encourage users to  do 
  1840.     this directly. */
  1841.  
  1842. constructor_function_in_class:
  1843.         declaration_specifier   constructor_parameter_list_and_body
  1844.         | TYPEDEFname           constructor_parameter_list_and_body
  1845.         ;
  1846.  
  1847.  
  1848.     /* The following conflicts with member declarations-
  1849.     constructor_parameter_list_and_body:
  1850.           parameter_type_list ';'
  1851.           | parameter_type_list constructor_init_list_opt compound_statement
  1852.           ;
  1853.     so parameter_type_list was expanded inline to get */
  1854.  
  1855.     /* C++, not ANSI C */
  1856. constructor_parameter_list_and_body:
  1857.           '('                           ')' type_qualifier_list_opt ';'
  1858.         | '(' type_name initializer     ')' type_qualifier_list_opt ';' 
  1859.         | '(' named_parameter_type_list ')' type_qualifier_list_opt ';'
  1860.         | '('                           ')' type_qualifier_list_opt
  1861.                 constructor_init_list_opt compound_statement
  1862.         | '(' type_name initializer     ')' type_qualifier_list_opt
  1863.                 constructor_init_list_opt compound_statement
  1864.         | '(' named_parameter_type_list ')' type_qualifier_list_opt
  1865.                 constructor_init_list_opt compound_statement
  1866.  
  1867.         | constructor_conflicting_parameter_list_and_body
  1868.         ;
  1869.  
  1870.  
  1871.     /* The following conflicted with member declaration-
  1872.     constructor_conflicting_parameter_list_and_body:
  1873.         '('   type_name ')'                 type_qualifier_list_opt ';'
  1874.         | '(' type_name ')'                 type_qualifier_list_opt
  1875.                 constructor_init_list_opt compound_statement
  1876.         ;
  1877.     so type_name was inline expanded to get the following... */
  1878.  
  1879.  
  1880.     /*  Note  that by inline expanding type_qualifier_opt in a few of 
  1881.     the following rules I can transform 3  RR  conflicts  into  3  SR 
  1882.     conflicts.  Since  all the conflicts have a look ahead of ';', it 
  1883.     doesn't  really  matter  (also,  there  are  no   bad   LALR-only 
  1884.     components in the conflicts) */
  1885.  
  1886. constructor_conflicting_parameter_list_and_body:
  1887.         '(' type_specifier                 ')' type_qualifier_list_opt
  1888.                 ';'
  1889.         | '(' basic_type_name              ')' type_qualifier_list_opt
  1890.                 ';'
  1891.  
  1892.         | '(' TYPEDEFname                  ')' type_qualifier_list_opt
  1893.                 ';'
  1894.  
  1895.         | '(' global_or_scoped_typedefname ')' type_qualifier_list_opt
  1896.                 ';'
  1897.  
  1898.         | '(' type_qualifier_list          ')' type_qualifier_list_opt
  1899.                 ';'
  1900.  
  1901.  
  1902.         | '(' type_specifier               abstract_declarator ')' type_qualifier_list_opt
  1903.                 ';'
  1904.         | '(' basic_type_name              abstract_declarator ')' type_qualifier_list_opt
  1905.                 ';'
  1906.  
  1907.         /* missing entry posted below */
  1908.  
  1909.         | '(' global_or_scoped_typedefname abstract_declarator ')' type_qualifier_list_opt
  1910.                 ';'
  1911.         | '(' type_qualifier_list          abstract_declarator ')' type_qualifier_list_opt
  1912.                 ';'
  1913.  
  1914.  
  1915.         | '(' type_specifier               ')' type_qualifier_list_opt
  1916.                 constructor_init_list_opt compound_statement
  1917.  
  1918.         | '(' basic_type_name              ')' type_qualifier_list_opt
  1919.                 constructor_init_list_opt compound_statement
  1920.  
  1921.         | '(' TYPEDEFname                  ')' type_qualifier_list_opt
  1922.                 constructor_init_list_opt compound_statement
  1923.  
  1924.         | '(' global_or_scoped_typedefname ')' type_qualifier_list_opt
  1925.                 constructor_init_list_opt compound_statement
  1926.  
  1927.         | '(' type_qualifier_list           ')' type_qualifier_list_opt
  1928.                 constructor_init_list_opt compound_statement
  1929.  
  1930.  
  1931.         | '(' type_specifier  abstract_declarator ')' type_qualifier_list_opt
  1932.                 constructor_init_list_opt compound_statement
  1933.  
  1934.         | '(' basic_type_name abstract_declarator ')' type_qualifier_list_opt
  1935.                 constructor_init_list_opt compound_statement
  1936.  
  1937.         /* missing entry posted below */
  1938.  
  1939.         | '(' global_or_scoped_typedefname abstract_declarator ')' type_qualifier_list_opt
  1940.                 constructor_init_list_opt compound_statement
  1941.  
  1942.         | '(' type_qualifier_list          abstract_declarator ')' type_qualifier_list_opt
  1943.                 constructor_init_list_opt compound_statement
  1944.  
  1945.         | constructor_conflicting_typedef_declarator
  1946.         ;
  1947.  
  1948.  
  1949.     /* The following have ambiguities with member declarations-
  1950.     constructor_conflicting_typedef_declarator:
  1951.       '(' TYPEDEFname abstract_declarator ')' type_qualifier_list_opt
  1952.                 ';'
  1953.       |  '(' TYPEDEFname abstract_declarator ')' type_qualifier_list_opt
  1954.                 constructor_init_list_opt compound_statement
  1955.       ;
  1956.     which can be deferred by expanding abstract_declarator, and in two
  1957.     cases parameter_qualifier_list, resulting in ...*/
  1958.  
  1959. constructor_conflicting_typedef_declarator:
  1960.         '(' TYPEDEFname unary_abstract_declarator          ')' type_qualifier_list_opt
  1961.                 ';'
  1962.  
  1963.         | '(' TYPEDEFname unary_abstract_declarator       ')' type_qualifier_list_opt
  1964.                 constructor_init_list_opt compound_statement
  1965.  
  1966.         | '(' TYPEDEFname postfix_abstract_declarator     ')' type_qualifier_list_opt
  1967.                 ';'
  1968.  
  1969.         | '(' TYPEDEFname postfix_abstract_declarator     ')' type_qualifier_list_opt
  1970.                 constructor_init_list_opt compound_statement
  1971.  
  1972.  
  1973.         | '(' TYPEDEFname postfixing_abstract_declarator  ')' type_qualifier_list_opt
  1974.                 ';'
  1975.  
  1976.         | '(' TYPEDEFname postfixing_abstract_declarator  ')' type_qualifier_list_opt
  1977.                 constructor_init_list_opt compound_statement
  1978.         ;
  1979.  
  1980.  
  1981. constructor_init_list_opt:
  1982.         /* nothing */
  1983.         | constructor_init_list
  1984.         ;
  1985.  
  1986. constructor_init_list:
  1987.         ':' constructor_init
  1988.         | constructor_init_list ',' constructor_init
  1989.         ;
  1990.  
  1991. constructor_init:
  1992.         IDENTIFIER   '(' argument_expression_list ')'
  1993.         | IDENTIFIER '('                          ')'
  1994.  
  1995.         | TYPEDEFname '(' argument_expression_list ')'
  1996.         | TYPEDEFname '('                          ')'
  1997.         | global_or_scoped_typedefname '(' argument_expression_list ')'
  1998.         | global_or_scoped_typedefname '('                          ')'
  1999.  
  2000.         | '(' argument_expression_list ')' /* Single inheritance ONLY*/
  2001.         | '(' ')' /* Is this legal? It might be default! */
  2002.         ;
  2003.  
  2004. declarator:
  2005.         identifier_declarator
  2006.         | typedef_declarator
  2007.         ;
  2008.  
  2009. typedef_declarator:
  2010.         paren_typedef_declarator          /* would be ambiguous as parameter*/
  2011.         | simple_paren_typedef_declarator /* also ambiguous */
  2012.         | parameter_typedef_declarator    /* not ambiguous as parameter*/
  2013.         ;
  2014.  
  2015. parameter_typedef_declarator:
  2016.         TYPEDEFname
  2017.         | TYPEDEFname postfixing_abstract_declarator
  2018.         | clean_typedef_declarator
  2019.         ;
  2020.  
  2021.  
  2022.     /*  The  following  have  at  least  one  '*'or '&'.  There is no 
  2023.     (redundant) '(' between the '*'/'&'  and  the  TYPEDEFname.  This 
  2024.     definition  is  critical  in  that  a redundant paren that it too 
  2025.     close to the TYPEDEFname (i.e.,  nothing  between  them  at  all) 
  2026.     would  make  the TYPEDEFname into a parameter list, rather than a 
  2027.     declarator.*/
  2028.  
  2029. clean_typedef_declarator:
  2030.         clean_postfix_typedef_declarator
  2031.         | asterisk_or_ampersand parameter_typedef_declarator
  2032.         | unary_modifier        parameter_typedef_declarator
  2033.         ;
  2034.  
  2035. clean_postfix_typedef_declarator:
  2036.         '('   clean_typedef_declarator ')'
  2037.         | '(' clean_typedef_declarator ')' postfixing_abstract_declarator
  2038.         ;
  2039.  
  2040.  
  2041.     /* The following have a redundant '(' placed immediately  to  the 
  2042.     left  of the TYPEDEFname.  This opens up the possibility that the 
  2043.     TYPEDEFname is really the start of a parameter list, and *not*  a 
  2044.     declarator*/
  2045.  
  2046. paren_typedef_declarator:
  2047.         postfix_paren_typedef_declarator
  2048.         | asterisk_or_ampersand '(' simple_paren_typedef_declarator ')'
  2049.         | unary_modifier        '(' simple_paren_typedef_declarator ')'
  2050.         | asterisk_or_ampersand '(' TYPEDEFname ')' /* redundant paren */
  2051.         | unary_modifier        '(' TYPEDEFname ')' /* redundant paren */
  2052.         | asterisk_or_ampersand paren_typedef_declarator
  2053.         | unary_modifier        paren_typedef_declarator
  2054.         ;
  2055.  
  2056. postfix_paren_typedef_declarator:
  2057.         '(' paren_typedef_declarator ')'
  2058.         | '(' simple_paren_typedef_declarator postfixing_abstract_declarator ')'
  2059.         | '(' TYPEDEFname postfixing_abstract_declarator ')'              /* redundant paren */
  2060.         | '(' paren_typedef_declarator ')' postfixing_abstract_declarator
  2061.         ;
  2062.  
  2063.  
  2064.     /*  The following excludes lone TYPEDEFname to help in a conflict 
  2065.     resolution.  We have special cased lone  TYPEDEFname  along  side 
  2066.     all uses of simple_paren_typedef_declarator */
  2067.  
  2068. simple_paren_typedef_declarator:
  2069.         '(' TYPEDEFname ')'
  2070.         | '(' simple_paren_typedef_declarator ')'
  2071.         ;
  2072.  
  2073. identifier_declarator:
  2074.         unary_identifier_declarator
  2075.         | paren_identifier_declarator
  2076.         ;
  2077.  
  2078.  
  2079.     /*  The  following  allows  "function return array of" as well as 
  2080.     "array of function returning".  It COULD be cleaned  up  the  way 
  2081.     abstract  declarators  have been.  This change might make it hard 
  2082.     to recover from user's syntax errors, whereas now they appear  as 
  2083.     simple constraint errors. */
  2084.  
  2085. unary_identifier_declarator:
  2086.         postfix_identifier_declarator
  2087.         | asterisk_or_ampersand identifier_declarator
  2088.         | unary_modifier        identifier_declarator
  2089.         ;
  2090.  
  2091. postfix_identifier_declarator:
  2092.         paren_identifier_declarator           postfixing_abstract_declarator
  2093.         | '(' unary_identifier_declarator ')'
  2094.         | '(' unary_identifier_declarator ')' postfixing_abstract_declarator
  2095.         ;
  2096.  
  2097. old_function_declarator:
  2098.         postfix_old_function_declarator
  2099.         | asterisk_or_ampersand old_function_declarator
  2100.         | unary_modifier      old_function_declarator
  2101.         ;
  2102.  
  2103.  
  2104.     /*  ANSI  C  section  3.7.1  states  "An identifier declared as a 
  2105.     typedef name shall not be redeclared as a parameter".  Hence  the 
  2106.     following is based only on IDENTIFIERs.
  2107.  
  2108.     Instead  of identifier_lists, an argument_expression_list is used 
  2109.     in  old  style  function   definitions.    The   ambiguity   with 
  2110.     constructors   required   the  use  of  argument  lists,  with  a 
  2111.     constraint verification of the list (e_g.: check to see that  the 
  2112.     "expressions" consisted of lone identifiers).
  2113.  
  2114.     An interesting ambiguity appeared:
  2115.         const constant=5;
  2116.         int foo(constant) ...
  2117.  
  2118.     Is  this an old function definition or constructor?  The decision 
  2119.     is made later by THIS grammar based on trailing context :-). This 
  2120.     ambiguity is probably what caused many parsers to give up on  old 
  2121.     style function definitions. */
  2122.  
  2123. postfix_old_function_declarator:
  2124.         paren_identifier_declarator '(' argument_expression_list ')'
  2125.         | '(' old_function_declarator ')'
  2126.         | '(' old_function_declarator ')' old_postfixing_abstract_declarator
  2127.         ;
  2128.  
  2129. old_postfixing_abstract_declarator:
  2130.         array_abstract_declarator /* array modifiers */
  2131.         | old_parameter_type_list  /* function returning modifiers */
  2132.         ;
  2133.  
  2134. abstract_declarator:
  2135.         unary_abstract_declarator
  2136.         | postfix_abstract_declarator
  2137.         | postfixing_abstract_declarator
  2138.         ;
  2139.  
  2140. postfixing_abstract_declarator:
  2141.         array_abstract_declarator
  2142.         | parameter_type_list
  2143.         ;
  2144.  
  2145. array_abstract_declarator:
  2146.         '[' ']'
  2147.         | '[' constant_expression ']'
  2148.         | array_abstract_declarator '[' constant_expression ']'
  2149.         ;
  2150.  
  2151. unary_abstract_declarator:
  2152.         asterisk_or_ampersand
  2153.         | unary_modifier
  2154.         | asterisk_or_ampersand abstract_declarator
  2155.         | unary_modifier        abstract_declarator
  2156.         ;
  2157.  
  2158. postfix_abstract_declarator:
  2159.         '(' unary_abstract_declarator ')'
  2160.         | '(' postfix_abstract_declarator ')'
  2161.         | '(' postfixing_abstract_declarator ')'
  2162.         | '(' unary_abstract_declarator ')' postfixing_abstract_declarator
  2163.         ;
  2164.  
  2165. asterisk_or_ampersand:
  2166.         '*'
  2167.         | '&'
  2168.         ;
  2169.  
  2170. unary_modifier:
  2171.         scope '*' type_qualifier_list_opt
  2172.         | asterisk_or_ampersand type_qualifier_list
  2173.         ;
  2174.  
  2175.  
  2176.  
  2177. /************************* NESTED SCOPE SUPPORT ******************************/
  2178.  
  2179.  
  2180.     /*  The  actions taken in the rules that follow involve notifying 
  2181.     the lexer that it should use the scope specified to determine  if 
  2182.     the  next  IDENTIFIER  token is really a TYPEDEFname token.  Note 
  2183.     that the actions must be taken before the parse has a  chance  to 
  2184.     "look-ahead" at the token that follows the "::", and hence should 
  2185.     be  done  during  a  reduction to "scoping_name" (which is always 
  2186.     followed by CLCL).  Since we are defining an  LR(1)  grammar,  we 
  2187.     are  assured  that  an action specified *before* the :: will take 
  2188.     place before the :: is shifted, and hence before the  token  that 
  2189.     follows the CLCL is scanned/lexed. */
  2190.  
  2191.     /*  Note that at the end of each of the following rules we should 
  2192.     be sure that the tag name is  in,  or  placed  in  the  indicated 
  2193.     scope.   If  no  scope  is  specified, then we must add it to our 
  2194.     current scope IFF it cannot  be  found  in  an  external  lexical 
  2195.     scope. */
  2196.  
  2197. scoping_name:
  2198.         tag_name
  2199.         | aggregate_key tag_name /* also update symbol table here by notifying it about a (possibly) new tag*/
  2200.         ;
  2201.  
  2202. scope:
  2203.         scoping_name CLCL
  2204.         | scope scoping_name  CLCL
  2205.         ;
  2206.  
  2207.  
  2208.     /*  Don't try to simplify the count of non-terminals by using one 
  2209.     of the other definitions of  "IDENTIFIER  or  TYPEDEFname"  (like 
  2210.     "label").   If you reuse such a non-terminal, 2 RR conflicts will 
  2211.     appear. The conflicts are LALR-only. The underlying cause of  the 
  2212.     LALR-only   conflict   is  that  labels,  are  followed  by  ':'.  
  2213.     Similarly, structure elaborations which provide a derivation have 
  2214.     have ':' just  after  tag_name  This  reuse,  with  common  right 
  2215.     context, is too much for an LALR parser. */
  2216.  
  2217. tag_name:
  2218.         IDENTIFIER
  2219.         | TYPEDEFname
  2220.         ;
  2221.  
  2222. global_scope:
  2223.         { /*scan for upcoming name in file scope */ } CLCL
  2224.         ;
  2225.  
  2226. global_or_scope:
  2227.         global_scope
  2228.         | scope
  2229.         | global_scope scope
  2230.         ;
  2231.  
  2232.  
  2233.     /*  The  following can be used in an identifier based declarator. 
  2234.     (Declarators  that  redefine  an  existing  TYPEDEFname   require 
  2235.     special  handling,  and are not included here).  In addition, the 
  2236.     following are valid "identifiers" in  an  expression,  whereas  a 
  2237.     TYPEDEFname is NOT.*/
  2238.  
  2239. scope_opt_identifier:
  2240.                 IDENTIFIER
  2241.         | scope IDENTIFIER  /* C++ not ANSI C */
  2242.         ;
  2243.  
  2244. scope_opt_complex_name:
  2245.                 complex_name
  2246.         | scope complex_name
  2247.         ;
  2248.  
  2249. complex_name:
  2250.         '~' TYPEDEFname
  2251.         | operator_function_name
  2252.         ;
  2253.  
  2254.  
  2255.     /*  Note that the derivations for global_opt_scope_opt_identifier 
  2256.     and global_opt_scope_opt_complex_name must be  placed  after  the 
  2257.     derivation:
  2258.  
  2259.        paren_identifier_declarator : scope_opt_identifier
  2260.  
  2261.     There  are several states with RR conflicts on "(", ")", and "[".  
  2262.     In these states we give up and assume a declaration, which  means 
  2263.     resolving   in  favor  of  paren_identifier_declarator.  This  is 
  2264.     basically the "If it can be  a  declaration  rule...",  with  our 
  2265.     finite cut off. */
  2266.  
  2267. global_opt_scope_opt_identifier:
  2268.         global_scope scope_opt_identifier
  2269.         |            scope_opt_identifier
  2270.         ;
  2271.  
  2272. global_opt_scope_opt_complex_name:
  2273.         global_scope scope_opt_complex_name
  2274.         |            scope_opt_complex_name
  2275.         ;
  2276.  
  2277.  
  2278.     /*  Note  that we exclude a lone TYPEDEFname.  When all alone, it 
  2279.     gets involved in a lot of ambiguities (re: function like cast  vs 
  2280.     declaration),   and  hence  must  be  special  cased  in  several 
  2281.     contexts. Note that generally every use of scoped_typedefname  is 
  2282.     accompanied by a parallel production using lone TYPEDEFname */
  2283.  
  2284. scoped_typedefname:
  2285.         scope TYPEDEFname
  2286.         ;
  2287.  
  2288. global_or_scoped_typedefname:
  2289.                        scoped_typedefname
  2290.         | global_scope scoped_typedefname
  2291.         | global_scope TYPEDEFname
  2292.         ;
  2293.  
  2294. global_opt_scope_opt_typedefname:
  2295.         TYPEDEFname
  2296.         | global_or_scoped_typedefname
  2297.         ;
  2298.  
  2299. %%
  2300. yyerror(string)
  2301. char*string;
  2302. {
  2303.     printf("parser error: %s\n", string);
  2304. }
  2305.  
  2306.  
  2307. main()
  2308. {
  2309.     yyparse();
  2310. }
  2311.